package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmc.cloud.cmclink.doc.api.document.rep.VesselOffHireMaintenanceRespDto;
import com.cmc.cloud.cmclink.doc.api.document.req.VesselOffHireMaintenanceReqDto;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.VesselOffHireMaintenanceErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.convert.VesselOffHireMaintenanceConvert;
import com.cmc.cloud.cmclink.doc.entity.VesselOffHireMaintenanceDO;
import com.cmc.cloud.cmclink.doc.mapper.VesselOffHireMaintenanceMapper;
import com.cmc.cloud.cmclink.doc.rpcservice.CustomerRpcService;
import com.cmc.cloud.cmclink.doc.service.VesselOffHireMaintenanceService;
import com.cmc.cloud.cmclink.doc.vo.vesseloffhiremaintenancevo.*;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.ex.Assertion;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 整船禁接的船舶维护 Service 实现类
 *
 * @author 集运管理员
 */
@Service
@Validated
public class VesselOffHireMaintenanceServiceImpl implements VesselOffHireMaintenanceService {

    @Resource
    private VesselOffHireMaintenanceMapper vesselOffHireMaintenanceMapper;
    @Resource
    private CustomerRpcService nameTransferService;

    @Override
    public void createVesselOffHireMaintenance(VesselOffHireMaintenanceCreateReqVO createReqVO) {
        // 插入
        VesselOffHireMaintenanceDO vesselOffHireMaintenance = BeanUtil.copyProperties(createReqVO, VesselOffHireMaintenanceDO.class);
        validateUniqueExists(createReqVO, null);
        vesselOffHireMaintenanceMapper.insert(vesselOffHireMaintenance);
    }

    @Override
    public void updateVesselOffHireMaintenance(VesselOffHireMaintenanceUpdateReqVO updateReqVO) {
        // 校验存在
        validateVesselOffHireMaintenanceExists(updateReqVO.getId());

        validateUniqueExists(updateReqVO, updateReqVO.getId());
        // 更新
        VesselOffHireMaintenanceDO updateObj = BeanUtil.copyProperties(updateReqVO, VesselOffHireMaintenanceDO.class);
        vesselOffHireMaintenanceMapper.updateById(updateObj);
    }

    /**
     * vesselCode 重复并且  beginDate 和endDate 有交叉就不能保存
     *
     * @param vo
     * @param id
     */
    private void validateUniqueExists(VesselOffHireMaintenanceBaseVO vo, Long id) {
        LambdaQueryWrapperX<VesselOffHireMaintenanceDO> queryWrapperX = new LambdaQueryWrapperX<VesselOffHireMaintenanceDO>()
                .eqIfPresent(VesselOffHireMaintenanceDO::getVesselCode, vo.getVesselCode());
        if (id != null) {
            queryWrapperX.ne(VesselOffHireMaintenanceDO::getId, id);
        }
        List<VesselOffHireMaintenanceDO> vesselOffHireMaintenanceDos = vesselOffHireMaintenanceMapper.selectList(queryWrapperX);
        if (CollectionUtil.isNotEmpty(vesselOffHireMaintenanceDos)) {
            vesselOffHireMaintenanceDos.forEach(entity -> {
                if (entity.getEndDate().after(vo.getEndDate())) {
                    if (entity.getBeginDate().before(vo.getEndDate())) {
                        throw ServiceExceptionUtil.exception(VesselOffHireMaintenanceErrorCodeConstants.VESSEL_OFF_HIRE_MAINTENANCE_DATE_ERROR);
                    }
                } else if (entity.getEndDate().before(vo.getEndDate())) {
                    if (vo.getBeginDate().before(entity.getEndDate())) {
                        throw ServiceExceptionUtil.exception(VesselOffHireMaintenanceErrorCodeConstants.VESSEL_OFF_HIRE_MAINTENANCE_DATE_ERROR);
                    }
                } else {
                    throw ServiceExceptionUtil.exception(VesselOffHireMaintenanceErrorCodeConstants.VESSEL_OFF_HIRE_MAINTENANCE_DATE_ERROR);
                }
            });
        }
    }

    @Override
    public void deleteVesselOffHireMaintenance(Long id) {
        // 校验存在
        validateVesselOffHireMaintenanceExists(id);
        // 删除
        vesselOffHireMaintenanceMapper.deleteById(id);
    }

    private void validateVesselOffHireMaintenanceExists(Long id) {
        if (vesselOffHireMaintenanceMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(VesselOffHireMaintenanceErrorCodeConstants.VESSEL_OFF_HIRE_MAINTENANCE_NOT_EXISTS);
        }
    }

    @Override
    public VesselOffHireMaintenanceDO getVesselOffHireMaintenance(Long id) {
        return vesselOffHireMaintenanceMapper.selectById(id);
    }

    @Override
    public List<VesselOffHireMaintenanceDO> getVesselOffHireMaintenanceList(Collection<Long> ids) {
        return vesselOffHireMaintenanceMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<VesselOffHireMaintenanceRespVO> getVesselOffHireMaintenancePage(VesselOffHireMaintenancePageReqVO reqVO) {
        LambdaQueryWrapper<VesselOffHireMaintenanceDO> queryWrapperX = new LambdaQueryWrapper<VesselOffHireMaintenanceDO>()
                .orderByAsc(VesselOffHireMaintenanceDO::getVesselCode);
        if (StringUtils.isNotEmpty(reqVO.getVesselCode())) {
            queryWrapperX.like(VesselOffHireMaintenanceDO::getVesselCode, reqVO.getVesselCode());
        }
        PageResult<VesselOffHireMaintenanceDO> pageResult = vesselOffHireMaintenanceMapper.selectPage(reqVO, queryWrapperX);

        List<VesselOffHireMaintenanceRespVO> results = BeanUtil.copyToList(pageResult.getList(), VesselOffHireMaintenanceRespVO.class);
        if (CollectionUtil.isNotEmpty(results)) {
            try {
                nameTransferService.fillVesselName(results);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new PageResult<>(results, pageResult.getTotal());
    }

    @Override
    public List<VesselOffHireMaintenanceRespDto> queryVesselOffHireMaintenance(VesselOffHireMaintenanceReqDto vesselOffHireMaintenanceReqDto) {
        LambdaQueryWrapperX<VesselOffHireMaintenanceDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        lambdaQueryWrapperX.likeIfPresent(VesselOffHireMaintenanceDO::getVesselCode, vesselOffHireMaintenanceReqDto.getVesselCode());
        List<VesselOffHireMaintenanceDO> vesselOffHireMaintenanceDOList = vesselOffHireMaintenanceMapper.selectList(lambdaQueryWrapperX);
        if (CollectionUtils.isEmpty(vesselOffHireMaintenanceDOList)) {
            return Collections.emptyList();
        }
        return VesselOffHireMaintenanceConvert.INSTANCE.convert(vesselOffHireMaintenanceDOList);
    }

    @Override
    public void checkVesselOffHireMaintenanceDate(List<String> vesselCodeList, LocalDate nowDate) {
        LambdaQueryWrapperX<VesselOffHireMaintenanceDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<>();
        lambdaQueryWrapperX.in(VesselOffHireMaintenanceDO::getVesselCode, vesselCodeList);
        lambdaQueryWrapperX.le(VesselOffHireMaintenanceDO::getBeginDate, nowDate);
        lambdaQueryWrapperX.ge(VesselOffHireMaintenanceDO::getEndDate, nowDate);
        List<VesselOffHireMaintenanceDO> list = vesselOffHireMaintenanceMapper.selectList(lambdaQueryWrapperX);
        if (CollectionUtils.isNotEmpty(list)) {
            List<String> vesselCodeErrorList = list.stream().map(e -> e.getVesselCode()).collect(Collectors.toList());
            Assertion.assertTrue(false).raise0(VesselOffHireMaintenanceErrorCodeConstants.VESSEL_OFF_HIRE_SPECIAL_DATE_ERROR.getCode(), StringUtils.join(vesselCodeErrorList, ","));
        }
    }
}
